#include <stdlib.h>
#include <string.h>
#include <mem/free.h>

static mem_t * mem_root = NULL;
static mem_t * mem_last = NULL;

static void attach_mem_to_list(mem_t * m) {
	if (!mem_last) {																	// 添加的第一个元素
		mem_root = m;
		mem_last = m;
		return;
	}

	m->previous		= mem_last;
	mem_last->next	= m;
	mem_last		= m;
}

static inline int get_mem_mgmt_size() {
	return (long) &(((mem_t *) NULL)->data);
}

void * mem_alloc(int size, bool zero_init) {
	if (size <= 0) return NULL;

	int mem_mgmt_size = get_mem_mgmt_size();											// 管理开销，包含previous,next, after_one_k, before_one_k, size

	mem_t * m = malloc(size + mem_mgmt_size);											// 分配内存块，包含管理开销

	memset(m, 0, mem_mgmt_size);														// 管理部分置0

	attach_mem_to_list(m);																// 添加到list尾端

	m->size = size;

	if (zero_init) memset(m->data, 0, size);											// 有些情况需要将数据库初始化为0

	return m->data;																		// 返回data的部分给用户使用
}

int get_mem_sizes() {
	int size = 0;

	for (mem_t * m = mem_root; m; m = m->next) size += m->size + get_mem_mgmt_size();

	return size;
}

int get_mem_blocks() {
	int i = 0;

	for (mem_t * m = mem_root; m; m = m->next) i++;

	return i;
}

static mem_t * data_to_mem_t(void * data) {
	char * pt = (char *) data;

	pt -= get_mem_mgmt_size();

	return (mem_t *) pt;
}

void safe_free(void * data) {
	if (!data) return;

	mem_t * pt = data_to_mem_t(data);

	mem_t * next		= pt->next;
	mem_t * previous	= pt->previous;

	if (next)		next->previous	= previous;											// 上一点与下一点相连，pt被断开了。
	if (previous)	previous->next	= next;

	free(pt);
}

void free_all(void) {
	for (mem_t * m = mem_root; m;) {
		mem_t * next = m->next;
		free(m);
		m = next;
	}
}
